<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="theme-color" content="#000000">
    <!--
      manifest.json provides metadata used when your web app is added to the
      homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
    -->
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json">
    <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
    <!--<script src="%PUBLIC_URL%/cornerstone-core/cornerstone.min.js"></script>-->
    <!--<script src="%PUBLIC_URL%/cornerstone-wado-image-loader/cornerstoneWADOImageLoader.min.js"></script>-->
    <!--<script src="%PUBLIC_URL%/cornerstone-wado-image-loader/cornerstoneWADOImageLoaderCodecs.min.js"></script>-->
    <!--<script src="%PUBLIC_URL%/cornerstone-wado-image-loader/cornerstoneWADOImageLoaderWebWorker.min.js"></script>-->
    <title>React App</title>
</head>
<body>
<noscript>
    You need to enable JavaScript to run this app.
</noscript>
<script id="mainVert" type="x-shader/x-vertex">
    varying vec2 vUv;

    void main() {
        vUv = uv;

        gl_Position =   projectionMatrix *
                        modelViewMatrix *
                        vec4(position,1.0);
    }

</script>
<script id="mainFrag" type="x-shader/x-fragment">
    #define R 5.0

    uniform sampler2D texture;
    uniform vec2 seedPoint;
    uniform vec2 imgSize;

    varying vec2 vUv;

    void main() {
        vec2 pstep = 1.0 / imgSize;
        vec3 outColor = texture2D(texture, vUv).rgb;
        if(seedPoint.x >= 0.0 && seedPoint.y >= 0.0){
            vec2 circle = vec2((vUv.x - seedPoint.x) * (vUv.x - seedPoint.x), (vUv.y - seedPoint.y) * (vUv.y - seedPoint.y));
            float r = R * pstep.x;
            if(circle.x + circle.y <= r * r){
                outColor = vec3(1.0, 0.0, 0.0);
            }
        }
        gl_FragColor = vec4(outColor, 1.0);
    }

</script>

<script id="thresholdFrag" type="x-shader/x-fragment">
    #define R 3.0
    #define THRESHOLD_BINARY 0
    #define THRESHOLD_TRUNCATE 1
    #define THRESHOLD_TO_ZERO 2
    #define INVERSE 1
    #define CHOOSE_THRESHOLD_POINT 1

    uniform sampler2D texture;
    uniform vec2 seedPoint;
    uniform vec2 imgSize;

    varying vec2 vUv;

    void main() {
        vec2 pstep = 1.0 / imgSize;
        float r = R * pstep.x;
        vec2 circle = vec2((vUv.x - seedPoint.x) * (vUv.x - seedPoint.x), (vUv.y - seedPoint.y) * (vUv.y - seedPoint.y));

        vec3 outColor = texture2D(texture, vUv).rgb;
        if(circle.x + circle.y <= r * r){
            outColor = vec3(1.0, 0.0, 0.0);
        }
        else{
            float threshold = texture2D(texture, seedPoint).r;
            outColor = outColor.r >= threshold ? outColor : vec3(0.0);
        }
        gl_FragColor = vec4(outColor, 1.0);
    }
</script>

<script id="blendFrag" type="x-shader/x-fragment">
    #define R 3.0

    uniform sampler2D texture;
    uniform sampler2D mask;
    uniform float alpha;

    uniform vec2 seedPoint;
    uniform vec2 imgSize;

    varying vec2 vUv;

    void main() {
    vec2 pstep = 1.0 / imgSize;
        float r = R * pstep.x;
        vec2 circle = vec2((vUv.x - seedPoint.x) * (vUv.x - seedPoint.x), (vUv.y - seedPoint.y) * (vUv.y - seedPoint.y));

        vec3 textureColor = texture2D(texture, vUv).rgb;
        vec3 maskColor = texture2D(mask, vUv).rgb;

        if(seedPoint.x >= 0.0 && seedPoint.y >= 0.0){
            vec2 circle = vec2((vUv.x - seedPoint.x) * (vUv.x - seedPoint.x), (vUv.y - seedPoint.y) * (vUv.y - seedPoint.y));
            float r = R * pstep.x;
            if(circle.x + circle.y <= r * r){
                gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
                return;
            }
        }
        if(maskColor.r > 0.0){
            gl_FragColor = vec4(textureColor * (1.0 - alpha) + vec3(0.0, 1.0, 0.0) * alpha, 1.0);
        }
        else{
            gl_FragColor = vec4(textureColor, 1.0);
        }
    }

</script>

<script id="mixFrag" type="x-shader/x-fragment">
    uniform sampler2D texture;
    uniform sampler2D mask;
    uniform float alpha;

    uniform vec2 seedPoint;
    uniform vec2 imgSize;

    varying vec2 vUv;

    void main() {
        vec3 textureColor = texture2D(texture, vUv).rgb;
        vec3 maskColor = texture2D(mask, vUv).rgb;
        maskColor = clamp(vec3(1.5) - abs(4.0 * vec3(maskColor) + vec3(-3, -2, -1)), vec3(0), vec3(1));
        gl_FragColor = vec4(textureColor * (1.0 - alpha) + maskColor * alpha, 1.0);
    }
</script>

<script id="cropFrag" type="x-shader/x-fragment">
    uniform sampler2D texture;
    uniform sampler2D mask;
    uniform float alpha;

    uniform vec2 seedPoint;
    uniform vec2 imgSize;

    #define OFFSET_SIZE 9

    varying vec2 vUv;

    vec3 getNeighbor(sampler2D t, vec2 uv, vec2 offset, vec2 step){
        return texture2D(t, uv + offset * step).rgb;
    }

    vec3 dilate(sampler2D t, vec2 uv, vec2 step){
        vec3 textureColor = texture2D(t, vUv).rgb;
        float maxValue;
        for(int i = -1; i <= 1; i++){
            for(int j = -1; j <= 1; j++){
                vec3 neighbor = getNeighbor(t, vUv, vec2(i, j), step);
                maxValue = max(neighbor.r, textureColor.r);
            }
        }
        return vec3(maxValue);
    }

    void main() {
//        ivec2 size = textureSize2D(texture, 0);
        float unitU = 1.0 / 512.0 * 1.0;
        float unitV = 1.0 / 512.0 * 1.0;
        vec3 textureColor = texture2D(texture, vUv).rgb;
//        vec3 maskColor = dilate(mask, vUv, vec2(unitU, unitV));
        vec3 maskColor = texture2D(mask, vUv).rgb;
        vec3 outputColor = textureColor * (1.0 - alpha);
        if(maskColor.r > 0.0){
            vec2 step = vec2(unitU, unitV);
            vec3 top = getNeighbor(mask, vUv, vec2(0.0, -1.0), step);
            vec3 right = getNeighbor(mask, vUv, vec2(1.0, 0.0), step);
            vec3 down = getNeighbor(mask, vUv, vec2(0.0, 1.0), step);
            vec3 left = getNeighbor(mask, vUv, vec2(-1.0, 0.0), step);
            vec3 topRight = getNeighbor(mask, vUv, vec2(1.0, -1.0), step);
            vec3 downRight = getNeighbor(mask, vUv, vec2(1.0, 1.0), step);
            vec3 downLeft = getNeighbor(mask, vUv, vec2(-1.0, 1.0), step);
            vec3 topLeft = getNeighbor(mask, vUv, vec2(-1.0, -1.0), step);
            int hasEdges = 0;
            hasEdges = top.r != maskColor.r ? 1 : 0;
            hasEdges = right.r != maskColor.r ? 1 : 0;
            hasEdges = down.r != maskColor.r ? 1 : 0;
            hasEdges = left.r != maskColor.r ? 1 : 0;
            hasEdges = topRight.r != maskColor.r ? 1 : 0;
            hasEdges = downRight.r != maskColor.r ? 1 : 0;
            hasEdges = downLeft.r != maskColor.r ? 1 : 0;
            hasEdges = topLeft.r != maskColor.r ? 1 : 0;
            if(hasEdges == 1)
                outputColor = vec3(1.0, 0.0, 0.0);
            else{
                outputColor = texture2D(texture, vUv).rgb;
            }
        }
        gl_FragColor = vec4(outputColor, 1.0);
    }

</script>

<script id="contourFrag" type="x-shader/x-fragment">
    uniform sampler2D texture;
    uniform sampler2D mask;
    uniform float alpha;

    uniform vec2 seedPoint;
    uniform vec2 imgSize;

    #define OFFSET_SIZE 9

    varying vec2 vUv;

    vec3 getNeighbor(sampler2D t, vec2 uv, vec2 offset, vec2 step){
        return texture2D(t, uv + offset * step).rgb;
    }

    vec3 dilate(sampler2D t, vec2 uv, vec2 step){
        vec3 textureColor = texture2D(t, vUv).rgb;
        float maxValue;
        for(int i = -1; i <= 1; i++){
            for(int j = -1; j <= 1; j++){
                vec3 neighbor = getNeighbor(t, vUv, vec2(i, j), step);
                maxValue = max(neighbor.r, textureColor.r);
            }
        }
        return vec3(maxValue);
    }

    void main() {
//        ivec2 size = textureSize2D(texture, 0);
        float unitU = 1.0 / 512.0 * 1.0;
        float unitV = 1.0 / 512.0 * 1.0;
        vec3 textureColor = texture2D(texture, vUv).rgb;
//        vec3 maskColor = dilate(mask, vUv, vec2(unitU, unitV));
        vec3 maskColor = texture2D(mask, vUv).rgb;
        vec3 outputColor = textureColor;
        if(maskColor.r > 0.0){
            vec2 step = vec2(unitU, unitV);
            vec3 top = getNeighbor(mask, vUv, vec2(0.0, -1.0), step);
            vec3 right = getNeighbor(mask, vUv, vec2(1.0, 0.0), step);
            vec3 down = getNeighbor(mask, vUv, vec2(0.0, 1.0), step);
            vec3 left = getNeighbor(mask, vUv, vec2(-1.0, 0.0), step);
            vec3 topRight = getNeighbor(mask, vUv, vec2(1.0, -1.0), step);
            vec3 downRight = getNeighbor(mask, vUv, vec2(1.0, 1.0), step);
            vec3 downLeft = getNeighbor(mask, vUv, vec2(-1.0, 1.0), step);
            vec3 topLeft = getNeighbor(mask, vUv, vec2(-1.0, -1.0), step);
            int hasEdges = 0;
            hasEdges = top.r != maskColor.r ? 1 : 0;
            hasEdges = right.r != maskColor.r ? 1 : 0;
            hasEdges = down.r != maskColor.r ? 1 : 0;
            hasEdges = left.r != maskColor.r ? 1 : 0;
            hasEdges = topRight.r != maskColor.r ? 1 : 0;
            hasEdges = downRight.r != maskColor.r ? 1 : 0;
            hasEdges = downLeft.r != maskColor.r ? 1 : 0;
            hasEdges = topLeft.r != maskColor.r ? 1 : 0;
            if(hasEdges == 1)
                outputColor = vec3(1.0, 0.0, 0.0);
        }
        gl_FragColor = vec4(outputColor, 1.0);
    }
</script>

<script id="heatmapFrag" type="x-shader/x-fragment">
    uniform sampler2D texture;

    varying vec2 vUv;

    void main() {
        vec4 t = texture2D(texture, vUv);
        gl_FragColor = vec4(clamp(vec3(1.5) - abs(4.0 * vec3(t) + vec3(-3, -2, -1)), vec3(0), vec3(1)), 1.0);
    }
</script>

<script id="inverseHeatmapFrag" type="x-shader/x-fragment">
    uniform sampler2D texture;

    varying vec2 vUv;

    void main() {
        vec4 t = texture2D(texture, vUv);
        gl_FragColor = vec4(vec3(1.0) - clamp(vec3(1.5) - abs(4.0 * vec3(t) + vec3(-3, -2, -1)), vec3(0), vec3(1)), 1.0);
    }
</script>

<script id="hotRedFrag" type="x-shader/x-fragment">
    uniform sampler2D texture;

    varying vec2 vUv;

    void main() {
        vec4 t = texture2D(texture, vUv);
        gl_FragColor = vec4(t.r, 0.0, 0.0, 1.0);
    }
</script>

<script id="hotGreenFrag" type="x-shader/x-fragment">
    uniform sampler2D texture;

    varying vec2 vUv;

    void main() {
        vec4 t = texture2D(texture, vUv);
        gl_FragColor = vec4(0.0, t.g, 0.0, 1.0);
    }
</script>

<script id="hotBlueFrag" type="x-shader/x-fragment">
    uniform sampler2D texture;

    varying vec2 vUv;

    void main() {
        vec4 t = texture2D(texture, vUv);
        gl_FragColor = vec4(0.0, 0.0, t.b, 1.0);
    }
</script>

<script id="inverseFrag" type="x-shader/x-fragment">
    uniform sampler2D texture;

    varying vec2 vUv;

    void main() {
        vec4 t = texture2D(texture, vUv);
        gl_FragColor = vec4(vec3(1.0) - t.rgb, 1.0);
    }
</script>

<script id="sobelFrag" type="x-shader/x-fragment">
    uniform sampler2D texture;
    uniform float threshold;
    varying vec2 vUv;

    #define KERNEL_SIZE 9

    uniform float kernel[9];
    uniform vec2 offset[9];
    uniform vec2 imgSize;

    float textureSize;

    const vec3 factor = vec3(0.27, 0.67, 0.06);

    vec3 getNeighbor(sampler2D t, vec2 uv, vec2 offset, vec2 step){
            return texture2D(t, uv + offset * step).rgb;
    }

    vec3 gray(in vec3 t){
        return vec3(dot(factor, t));
    }

    vec3 gaussian(in vec2 coord, in sampler2D t){
        vec3 res = vec3(0);
        vec2 pstep = vec2(1.0) / vec2(128) * 3.0;
        res += texture2D(t, coord + vec2(-1.0, -1.0) * pstep).rgb;
        res += 2.0 * texture2D(t, coord + vec2(0.0, -1.0) * pstep).rgb;
        res += texture2D(t, coord + vec2(1.0, -1.0) * pstep).rgb;

        res += 2.0 * texture2D(t, coord + vec2(-1.0, 0.0) * pstep).rgb;
        res += 4.0 * texture2D(t, coord + vec2(0.0, 0.0) * pstep).rgb;
        res += 2.0 * texture2D(t, coord + vec2(1.0, 0.0) * pstep).rgb;

        res += texture2D(t, coord + vec2(-1.0, 1.0) * pstep).rgb;
        res += 2.0 * texture2D(t, coord + vec2(0.0, 1.0) * pstep).rgb;
        res += texture2D(t, coord + vec2(1.0, 1.0) * pstep).rgb;
        res /= vec3(16.0);
        return res;
    }

    vec3 sobel_x(in vec2 coord, in sampler2D t){
        vec3 res = vec3(0);
        vec2 pstep = vec2(1.0) / vec2(512.0) * 1.5;
        res -= gray(texture2D(t, coord + vec2(-1.0, -1.0) * pstep).rgb);
        res += gray(texture2D(t, coord + vec2(1.0, -1.0) * pstep).rgb);
        res -= 2.0 * gray(texture2D(t, coord + vec2(-1.0, 0.0) * pstep).rgb);
        res += 2.0 * texture2D(t, coord + vec2(1.0, 0.0) * pstep).rgb;
        res -= gray(texture2D(t, coord + vec2(-1.0, 1.0) * pstep).rgb);
        res += gray(texture2D(t, coord + vec2(1.0, 1.0) * pstep).rgb);
        return res;
    }

    vec3 sobel_y(in vec2 coord, in sampler2D t){
        vec3 res = vec3(0);
        vec2 pstep = vec2(1.0) / vec2(512.0) * 1.5;
        res -= gray(texture2D(t, coord + vec2(-1.0, -1.0) * pstep).rgb);
        res -= 2.0 * gray(texture2D(t, coord + vec2(0.0, -1.0) * pstep).rgb);
        res -= 1.0 * gray(texture2D(t, coord + vec2(1.0, -1.0) * pstep).rgb);

        res += gray(texture2D(t, coord + vec2(-1.0, 0.0) * pstep).rgb);
        res += 2.0 * gray(texture2D(t, coord + vec2(0.0, 1.0) * pstep).rgb);
        res += gray(texture2D(t, coord + vec2(1.0, 1.0) * pstep).rgb);
        return res;
    }

    vec3 apply(in vec2 coord, in sampler2D t){
        float threshold = 0.2;
        vec3 x = sobel_x(coord, t);
        vec3 y = sobel_y(coord, t);
        vec3 val = sqrt(x*x + y*y);
        vec3 inp = gray(texture2D(t, coord).rgb);
        float r = inp.r;
        float g = inp.g;
        float b = inp.b;
        r = val.x > threshold ? 0.0 : 1.0;
        g = val.y > threshold ? 0.0 : 1.0;
        b = val.z > threshold ? 0.0 : 1.0;
        return gray(vec3(r, g, b));
    }


    void main(void)
    {
        vec3 texel = apply(vUv, texture);
        gl_FragColor = vec4(texel, 1.0);
    }
</script>

<script id="sharpenFrag" type="x-shader/x-fragment">
uniform sampler2D texture;
varying vec2 vUv;

#define KERNEL_SIZE 9

uniform float kernel[9];
uniform vec2 offset[9];
uniform vec2 imgSize;

vec3 apply(in sampler2D colorTexture, in vec2 texcoord)
{

    vec2 pstep = vec2(1.0) / vec2(128);
	vec4 res  = vec4(0.0);

    res -= texture2D(colorTexture, texcoord + vec2(0.0, -1.0) * pstep);
    res -= texture2D(colorTexture, texcoord + vec2(-1.0, 0.0) * pstep);
    res += texture2D(colorTexture, texcoord + vec2(0.0, 0.0) * pstep) * 5.0;
    res -= texture2D(colorTexture, texcoord + vec2(1.0, 0.0) * pstep);
    res -= texture2D(colorTexture, texcoord + vec2(0.0, 1.0) * pstep);
    return vec3(res);
}

void main(void)
{
	vec3 texel = apply(texture, vUv);
	gl_FragColor = vec4(texel, 1.0);
}
</script>

<script id="embossFrag" type="x-shader/x-fragment">
uniform sampler2D texture;
varying vec2 vUv;

// Ядро свертки
#define KERNEL_SIZE 9

uniform float kernel[9];
uniform vec2 offset[9];
uniform vec2 imgSize;

const vec3 factor = vec3(0.27, 0.67, 0.06);

vec3 apply(in sampler2D colorTexture, in vec2 texcoord)
{

    vec2 pstep = vec2(1.0) / vec2(128);
	vec4 res  = vec4(0.0);

    res -= 2.0 * texture2D(colorTexture, texcoord + vec2(-1.0, -1.0) * pstep);
    res -= texture2D(colorTexture, texcoord + vec2(0.0, -1.0) * pstep);
    res -= texture2D(colorTexture, texcoord + vec2(-1.0, 0.0) * pstep);
    res += texture2D(colorTexture, texcoord + vec2(0.0, 0.0) * pstep);
    res += texture2D(colorTexture, texcoord + vec2(1.0, 0.0) * pstep);
    res += texture2D(colorTexture, texcoord + vec2(0.0, 1.0) * pstep);
    res += 2.0 * texture2D(colorTexture, texcoord + vec2(1.0, 1.0) * pstep);
    return vec3(dot(factor, res.rgb));
}

void main(void)
{
	vec3 texel = apply(texture, vUv);
	gl_FragColor = vec4(texel, 1.0);
}
</script>

<script id="laplacianFrag" type="x-shader/x-fragment">
    uniform sampler2D texture;

    varying vec2 vUv;

    #define KERNEL_SIZE 9
    uniform vec2 imgSize;

    uniform float kernel[9];
    uniform vec2 offset[9];

    const vec3 factor = vec3(0.27, 0.67, 0.06);

    vec3 gray(in vec3 t){
        return vec3(dot(factor, t));
    }

    vec3 apply(in sampler2D colorTexture, in vec2 texcoord)
    {
        float pstepX = 1.0 / imgSize.x * 1.0;
        float pstepY = 1.0 / imgSize.y * 1.0;
        vec3 res  = vec3(0.0);
        res += gray(texture2D(colorTexture, texcoord + vec2(pstepX, -pstepY)).rgb);
        res += gray(texture2D(colorTexture, texcoord + vec2(-pstepX, 0.0)).rgb);
        res -= 4.0 * gray(texture2D(colorTexture, texcoord + vec2(pstepX, -pstepY)).rgb);
        res += gray(texture2D(colorTexture, texcoord + vec2(pstepX, 0.0)).rgb);
        res += gray(texture2D(colorTexture, texcoord + vec2(0.0, pstepY)).rgb);
        return vec3(res);
    }

    void main(void)
    {
        vec3 texel = apply(texture, vUv);
        gl_FragColor = vec4(texel, 1.0);
    }
</script>

<script id="medianBlurFrag" type="x-shader/x-fragment">
    uniform sampler2D texture;

    varying vec2 vUv;
    uniform vec2 imgSize;

    #define KERNEL_SIZE 9

    float ns[KERNEL_SIZE];

    vec3 apply(in sampler2D colorTexture, in vec2 texcoord)
    {
        float pstepX = 1.0 / imgSize.x * 1.0;
        float pstepY = 1.0 / imgSize.y * 1.0;
        vec3 res  = vec3(0.0);

        for(int i = -1; i <= 1; i++){
            for(int j = -1; j <= 1; j++){
                ns[(1 + i) * 3 + j] = texture2D(colorTexture, texcoord + vec2(float(i) * pstepX, float(j) * pstepY)).r;
            }
        }

        for(int i = 1; i < KERNEL_SIZE; i++){
            for(int j = 0; j < KERNEL_SIZE - 1; j++){
                if(ns[j] > ns[i]){
                   float swap = ns[j];
                   ns[j] = ns[i];
                   ns[i] = swap;
                }
            }
        }
        return vec3(ns[KERNEL_SIZE / 2]);
    }

    void main(void)
    {
        vec3 texel = apply(texture, vUv);
        gl_FragColor = vec4(texel, 1.0);
    }
</script>


<div id="root" style="height: 100%; min-height: 300px; min-width: 1000px;"></div>
<script>

</script>
</body>
</html>
